package cn.example.demo.modules.sys.service;

import cn.example.demo.common.model.service.ServiceResult;
import cn.example.demo.common.retrieval.PageBean;
import cn.example.demo.common.secure.context.LoginUserApi;
import cn.example.demo.common.secure.dto.LoginUser;
import cn.example.demo.common.tools.QueryServiceUtils;
import cn.example.demo.common.tools.obj.reflect.EntityUtils;
import cn.example.demo.modules.sys.model.dto.SysLogDto;
import cn.example.demo.modules.sys.model.entity.SysLog;
import cn.example.demo.modules.sys.mapper.SysLogMapper;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 描述：【系统日志】接口实现类
 */
@Service
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements ISysLogService {
    @Autowired
    private LoginUserApi loginUserApi;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult insertSysLog(SysLogDto sysLogDto) {
        SysLog entity = EntityUtils.entityConvert(sysLogDto, new SysLog(), false);

        // 其他信息填充
        LoginUser currentLoginUser = loginUserApi.getCurrentLoginUser();

        if (this.save(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【系统日志，ID:{}】创建成功!", entity.getId()), entity);
        }

        return ServiceResult.isInternalError("【系统日志】创建失败，未知错误！");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult updateSysLog(SysLogDto sysLogDto) {
        SysLog entity = this.getById(sysLogDto.getId());
        if (entity == null) {
            return ServiceResult.isNotFound(StrUtil.format("【系统日志】信息更新失败：记录不存在！ID:{}", sysLogDto.getId()));
        }

        entity = EntityUtils.entityConvert(sysLogDto, entity, true);
        if (this.updateById(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【系统日志，ID:{}】信息更新成功!", entity.getId()), null);
        }

        return ServiceResult.isNotModified("未知错误，【系统日志】信息修改失败！");
    }

    @Override
    public PageBean querySysLog(SysLogDto sysLogDto) {
        Page pageResult = PageHelper.startPage(sysLogDto.getPageNum(), sysLogDto.getPageSize())
                .doSelectPage(() -> this.list(getQueryWrapper(sysLogDto)));

        return QueryServiceUtils.encapsulatePageBean(new PageBean<>(), pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteSysLog(SysLogDto sysLogDto) {
        int rows = this.baseMapper.deleteBatchIds(sysLogDto.getIds());
        if (rows > 0) {
            return ServiceResult.isSuccess(StrUtil.format("操作成功，已批量删除【系统日志】共 {} 条记录！", rows), rows);
        }

        return ServiceResult.isNotModified("删除【系统日志】失败，请稍后重试！");
    }

    @Override
    public SysLog findSysLogById(String id) {
        return this.getById(id);
    }

    /**
     * 查询条件
     *
     * @param sysLogDto
     * @return
     */
    protected LambdaQueryWrapper getQueryWrapper(SysLogDto sysLogDto) {
        LambdaQueryWrapper<SysLog> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(StrUtil.isNotBlank(sysLogDto.getId()), SysLog::getId, sysLogDto.getId());
        wrapper.eq(sysLogDto.getOperatorId() != null, SysLog::getOperatorId, sysLogDto.getOperatorId());
        wrapper.like(StrUtil.isNotBlank(sysLogDto.getOperation()), SysLog::getOperation, sysLogDto.getOperation());
        wrapper.like(StrUtil.isNotBlank(sysLogDto.getRequestMethod()), SysLog::getRequestMethod, sysLogDto.getRequestMethod());
        wrapper.like(StrUtil.isNotBlank(sysLogDto.getResourcePath()), SysLog::getResourcePath, sysLogDto.getResourcePath());
        wrapper.eq(sysLogDto.getStatus() != null, SysLog::getStatus, sysLogDto.getStatus());
        wrapper.eq(sysLogDto.getConsumeTime() != null, SysLog::getConsumeTime, sysLogDto.getConsumeTime());
        wrapper.ge(sysLogDto.getOperationTimeStart() != null, SysLog::getOperationTime, sysLogDto.getOperationTimeStart());
        wrapper.le(sysLogDto.getOperationTimeEnd() != null, SysLog::getOperationTime, sysLogDto.getOperationTimeEnd());
        wrapper.like(StrUtil.isNotBlank(sysLogDto.getClientIp()), SysLog::getClientIp, sysLogDto.getClientIp());
        wrapper.like(StrUtil.isNotBlank(sysLogDto.getOperator()), SysLog::getOperator, sysLogDto.getOperator());

        wrapper.orderByDesc(SysLog::getOperationTime);

        return wrapper;
    }
}
